Necesito crear un método de pérdida personalizado basado en BLEU. Estoy pasando mi LabelEncoder en el constructor para invertir etiquetas y predicciones y calcular la distancia azul.
Aquí está mi clase de pérdida
class CIMCodeSuccessiveLoss(Loss): def __init__(self, labelEncoder: LabelEncoder): super().__init__() self.le = labelEncoder def bleu_score(self, true_label, pred_label): cim_true_label = self.le.inverse_transform(true_label.numpy()) cim_pred_label = self.le.inverse_transform(pred_label.numpy()) bleu_scores = [sentence_bleu(list(one_true_label), list(one_pred_label), weights=(0.5, 0.25, 0.125, 0.125)) for one_true_label, one_pred_label in zip(cim_true_label, cim_pred_label)] return np.float32(bleu_scores) def call(self, y_true, y_pred): labeled_y_pred = tf.cast(tf.argmax(y_pred, axis=-1), tf.int32) bleu = tf.py_function(self.bleu_score, (tf.reshape(y_true, [-1]), labeled_y_pred), tf.float32) return tf.reduce_sum(tf.square(1 - bleu))El método bleu_score calcula las puntuaciones correctas y devuelve una matriz NumPy. cuando trato de devolver la suma al cuadrado, aparece este error
raise ValueError(f"No gradients provided for any variable: {variable}.También estoy proporcionando el modelo:
inputs = tf.keras.Input(shape=(1,), dtype=tf.string) x = vectorize_layer(inputs) x = Embedding(vocab_size, embedding_dim, name="embedding")(x) x = LSTM(units=32, name="lstm")(x) outputs = Dense(classes_number, name="classification")(x) model = tf.keras.Model(inputs=inputs, outputs=outputs, name="first_cim_classifier") model.summary() # we add early stopping for our model. early_stopping = EarlyStopping(monitor='loss', patience=2) model.compile( loss=CIMCodeSuccessiveLoss(le), optimizer=tf.keras.optimizers.Adam(), metrics=["accuracy", "crossentropy"], run_eagerly=True) trained_model = model.fit(np.array(x_train), np.array(y_train), batch_size=64, epochs=10, validation_data=(np.array(x_val), np.array(y_val)), callbacks=[early_stopping])Cualquier ayuda es apreciada. Gracias por adelantado.
Para calcular la función de pérdida, utiliza el método 'tf.argmax(y_pred, axis=-1)', argmax no es diferenciable y la diferenciación automática para calcular los gradientes no es posible, debe eliminar este método, por ejemplo ( dependiendo de sus datos) puede cambiar la capa de salida a softmax y las etiquetas a one_hot.